/*
    文件内容: 封装TcpServer相关操作,封装创建Socket和EventLoop调用的地方,让main更加简洁
    文件名: TcpServer.h
    作者: 中国好青年(码农论坛)
    时间: 2024/9/8

*/
#include "TcpServer.h"

/* 
    函数名: TcpServer(const std::string &ip, uint16_t port)
    返回值: 无
    参  数: const std::string &ip, IP地址; uint16_t port, 端口号;
    函数作用: TcpServer构造函数,创建Acceptor处理bind,listen,和channel回调函数
*/
TcpServer::TcpServer(const std::string &ip, uint16_t port, int timeout, int threadnums)
                    :threadnums_(threadnums), mainloop_(new EventLoop(true,10,5)),acceptserver_(mainloop_.get(), ip, port),threadpool_(threadnums_, "IO")
{
    //主reactor
    mainloop_ -> setepolltimeoutcallback(std::bind(&TcpServer::epolltimeout, this, std::placeholders::_1));
    mainloop_ -> setEpollTimeoutVal(timeout);

    acceptserver_.setNewconnCallback(std::bind(&TcpServer::newConnection, this,std::placeholders::_1));

    //从reactor 个数=线程数=vector个数
    for(int i = 0; i < threadnums_; i++)
    {
        subloops_.emplace_back(new EventLoop(false,10,5));
        subloops_[i] -> setepolltimeoutcallback(std::bind(&TcpServer::epolltimeout, this, std::placeholders::_1));
        subloops_[i] -> setTimerCallback(std::bind(&TcpServer::removeConnfromMap, this, std::placeholders::_1));
        subloops_[i] -> setEpollTimeoutVal(timeout);
        this -> threadpool_.addtask(std::bind(&EventLoop::run, subloops_[i].get()));
    }
}

/* 
    函数名: ~TcpServer()
    返回值: 无
    参  数: 无
    函数作用: 析构函数
*/
TcpServer::~TcpServer()
{

}

/*
    函数名: start()
    返回值: 无
    参  数: 无
    函数作用: 监听该函数loop循环事件
*/
void TcpServer::start()
{
    mainloop_ -> run();
}

/*
    函数名: start()
    返回值: 无
    参  数: 无
    函数作用: 监听该函数loop循环事件
*/
void TcpServer::stop()
{   
    mainloop_ -> stop();
    debug("stop mainloop\n");
    for(int index = 0; index < threadnums_; index++)
    {
        subloops_[index] -> stop();
    }
    debug("stop subloops\n");
    threadpool_.stop();
}
/* 
    函数名: newConnection(std::unique_ptr<Socket> clientsock)
    返回值: 无
    参  数: 监听fd的sock类
    函数作用: 处理新连接上来的数据,从Accept中抽离出来
*/
void TcpServer::newConnection(std::unique_ptr<Socket> clientsock)
{   
    debug("add connection to conns %d \n",syscall(SYS_gettid));
    spConnection conn(new Connection(subloops_[clientsock->fd() % threadnums_].get(), std::move(clientsock)));
    conn -> setcloseconncallback(std::bind(&TcpServer::closeConnection, this, std::placeholders::_1));
    conn -> seterrorconncallback(std::bind(&TcpServer::errorConnection, this, std::placeholders::_1));
    conn -> setonmessagecallback(std::bind(&TcpServer::onmessage, this, std::placeholders::_1, std::placeholders::_2));
    conn -> setsendCompletecallback(std::bind(&TcpServer::sendComplete, this,  std::placeholders::_1));
    
    {
        std::lock_guard<std::mutex> lg(mutex_);
        conns[conn -> fd()] = conn;
    }
    subloops_[conn->fd() % threadnums_] -> newconnection(conn);

    debug("传递状态给 echoserver\n");
    if(newconnectioncallback_)
    {
        newconnectioncallback_(conn);
    }
}

/* 
    函数名: closeConnection(spConnection conn)
    返回值: 无
    参  数: spConnection conn
    函数作用: 客户端关闭调用的函数,在创建Connection对象时赋值。
*/
void TcpServer::closeConnection(spConnection conn)
{   
    
    {
        std::lock_guard<std::mutex> lg(mutex_);
        conns.erase(conn->fd());
    }

    if(closeconnectioncallback_)
    {
        closeconnectioncallback_(conn);
    }
   
}

/* 
    函数名: errorConnection(spConnection conn)
    返回值: 无
    参  数: spConnection  conn
    函数作用: 客户端错误调用的函数, 在创建Connection对象时赋值。
*/
void TcpServer::errorConnection(spConnection conn)
{   
    {
        std::lock_guard<std::mutex> lg(mutex_);
        conns.erase(conn->fd());
    }
    if(errorconnectioncallback_)
    {
        errorconnectioncallback_(conn);
    }
}

/* 
    函数名: onmessage(spConnection conn, std::string message)
    返回值: 无
    参  数: spConnection conn, 连接上来的Connection客户端对象; std::string message, 收到的message
    函数作用: 绑定到Connection类中的函数,用来处理收发数据
*/
void TcpServer::onmessage(spConnection conn, std::string &message)
{
    if(onmessagecallback_)
    {
        onmessagecallback_(conn, message);
    }
}

/* 
    函数名: sendComplete(spConnection conn)
    返回值: 无
    参  数: spConnection conn, 连接上来的Connection客户端对象
    函数作用: 回调函数，绑定在Connection::sendcomletecallback_上，发送完成了调用
*/
void TcpServer::sendComplete(spConnection conn)
{   
    if(sendcompletecallback_)
    {
        sendcompletecallback_(conn);
    }
}

/* 
    函数名: epolltimeout(EventLoop *eploop)
    返回值: 无
    参  数: EventLoop *eploop,eloop对象
    函数作用: 在EventLoop中run中调用,当返回有事件对象为0就认为是超时
*/
void TcpServer::epolltimeout(EventLoop *eploop)
{
    if(epolltimeoutcallback_)
    {
        epolltimeoutcallback_(eploop);
    }
}

void TcpServer::removeConnfromMap(int fd)
{
    {
        std::lock_guard<std::mutex> lg(mutex_);
        conns.erase(fd);
    }
}

/* 
    函数名: setNewConnectionCallback(std::function <void(spConnection conn)> newconnectioncallback)
    返回值: 无
    参  数: std::function <void(spConnection conn)> newconnectioncallback, 函数对象
    函数作用: 设置回调函数值,在newConnection中调用,绑定EchoServer函数
*/
void TcpServer::setNewConnectionCallback(std::function <void(spConnection conn)> newconnectioncallback)
{
    newconnectioncallback_ = newconnectioncallback;
}

/* 
    函数名: setCloseConnectionCallback(std::function <void(spConnection conn)> closeconnectioncallback)
    返回值: 无
    参  数: std::function <void(spConnection conn)> closeconnectioncallback, 函数对象
    函数作用: 设置回调函数值,在errorConnection中调用,绑定EchoServer函数
*/
void TcpServer::setCloseConnectionCallback(std::function <void(spConnection conn)> closeconnectioncallback)
{
    closeconnectioncallback_ = closeconnectioncallback;
}

/* 
    函数名: setErrorConnectionCallback(std::function <void(spConnection conn)> errorconnectioncallback)
    返回值: 无
    参  数: std::function <void(spConnection conn)> errorconnectioncallback, 函数对象
    函数作用: 设置回调函数值,在errorConnection中调用,绑定EchoServer函数
*/
void TcpServer::setErrorConnectionCallback(std::function <void(spConnection conn)> errorconnectioncallback)
{
    errorconnectioncallback_ = errorconnectioncallback;
}

/* 
    函数名: setOnmessageCallback(std::function <void(spConnection conn, std::string &message)> onmessagecallback)
    返回值: 无
    参  数: std::function <void(spConnection conn, std::string &message)> onmessagecallback, 函数对象
    函数作用: 设置回调函数值,在onMessage中调用,绑定EchoServer函数
*/
void TcpServer::setOnmessageCallback(std::function <void(spConnection conn, std::string &message)> onmessagecallback)
{
    onmessagecallback_ = onmessagecallback;
}

/* 
    函数名: setSendCompleteCallback(std::function <void(spConnection)> sendcompletecallback)
    返回值: 无
    参  数: std::function <void(spConnection)> sendcompletecallback, 函数对象
    函数作用: 设置回调函数值,在sendcomplete中调用,绑定EchoServer函数
*/
void TcpServer::setSendCompleteCallback(std::function <void(spConnection)> sendcompletecallback)
{
    sendcompletecallback_ = sendcompletecallback;
}

/* 
    函数名: setsetEpollTimeoutCallback(std::function <void(EventLoop *eploop)> epolltimeoutcallback)
    返回值: 无
    参  数: std::function <void(EventLoop *eploop)> epolltimeoutcallback, 函数对象
    函数作用: 设置回调函数值,在epollTimeout中调用,绑定EchoServer函数
*/
void TcpServer::setsetEpollTimeoutCallback(std::function <void(EventLoop *eploop)> epolltimeoutcallback)
{
    epolltimeoutcallback_ = epolltimeoutcallback;
}